package com.rem.stream.part1;

import com.rem.lambda.part1.Employee;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Stream 的终止操作====规约与收集
 *
 * @Author Rem
 * @Date 2020-02-13
 */

public class TestStream6 {

    List<Employee> employees = Arrays.asList(
            new Employee("张三", 16, 3468.12, Employee.State.BUSY),
            new Employee("李四", 42, 9485.32, Employee.State.FREE),
            new Employee("王五", 24, 5124.4, Employee.State.VOCATION),
            new Employee("赵六", 33, 6381.82, Employee.State.FREE),
            new Employee("田七", 36, 4448.45, Employee.State.BUSY),
            new Employee("方八", 36, 7485.42, Employee.State.VOCATION)
    );

    /**
     * 规约
     * <p>
     * Optional<T> reduce(BinaryOperator<T> accumulator);
     * T reduce(T identity, BinaryOperator<T> accumulator);
     * <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);
     * <p>
     * 可以将流中元素反复结合起来，得到一个值
     */


    //Optional<T> reduce(BinaryOperator<T> accumulator);
    //求总工资是多少
    @Test
    public void test() {
        Optional<Double> reduce = employees.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println(reduce.get());


        List<String> list = Arrays.asList("aaa", "fff", "ccc");
        Optional<String> reduce2 = list.stream().reduce((s1, s2) -> s1 + s2);
        System.err.println(reduce2.get());
    }


    // T reduce(T identity, BinaryOperator<T> accumulator);
    // identity:起始值
    @Test
    public void test2() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);

        Integer sum = list.stream()
                .reduce(100, (x, y) -> x + y);
        System.err.println(sum);
    }

    /**
     * 收集
     * collect ======将流转换为其他形式。接收一个Collector接口的实现，用于给Stream中元素做汇总的方法
     */
    @Test
    public void test3() {
        List<String> list = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());

        list.forEach(System.out::println);

        System.out.println("--------------------");


        HashSet<String> hashSetList = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));

        hashSetList.forEach(System.out::println);

    }

    @Test
    public void Test2() {

        //求总数
        Long count = employees.stream()
                .collect(Collectors.counting());
        System.out.println(count);

        //平均值
        Double avg = employees.stream()
                .collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(avg);

        //总和
        Double sumSalary = employees.stream()
                .collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println(sumSalary);


        //工资最高的人
        Optional<Employee> maxEmp = employees.stream()
                .collect(Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)));
        System.out.println(maxEmp.get());


        //最小工资
        Optional<Double> max = employees.stream()
                .map(Employee::getSalary)
                .min(Double::compare);
        System.out.println(max.get());


        //summarizingDouble  得到总数量  平均值  最大是  最小值  总值
        DoubleSummaryStatistics salaryALL = employees.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(salaryALL);
    }

    @Test
    public void Test3() {
        //分组
        //按照状态分组
        Map<Employee.State, List<Employee>> map = employees.stream()
                .collect(Collectors.groupingBy(Employee::getState));
        map.forEach((state, employees1) -> System.out.println(employees1));


        //分区
        //按照年龄段分区
        Map<Boolean, List<Employee>> map2 = employees.stream()
                .collect(Collectors.partitioningBy(e -> e.getAge() > 35));

        System.out.println(map2);


        //连接
        String str = employees.stream()
                .map(Employee::getName)
                // .reduce((x,y)->x+y).get(); //等同于下面
                .collect(Collectors.joining());

        //连接
        String str2 = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",","====","===="));
        System.out.println(str2);
    }

}
